package org.xnat.xnatfs.asset;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.junit.Before;
import org.junit.Test;
import org.xnat.xnatfs.exception.RequestException;

import com.bradmcevoy.http.Auth;

public class TestAssetProvider {
  private static final String SAMPLE_URL = "/projects?format=json";
  private static final Auth SAMPLE_AUTH = new Auth ( "johnson" );

  private HttpResponse expectedResponse;
  private NoHttpAssetProvider provider;

  @Before
  public void setUp () throws Exception {
    provider = new NoHttpAssetProvider ();

    expectedResponse = mockResponse ();
    provider.setResponse ( expectedResponse );
  }

  @Test
  public void shouldProvideStreamAsset () throws Exception {
    IStreamAsset asset = provider.getStreamAsset ( SAMPLE_URL, SAMPLE_AUTH );
    assertNotNull ( asset );
    assertEquals ( SAMPLE_URL, provider.getUrl () );
    assertEquals ( SAMPLE_AUTH, provider.getAuth () );
  }

  @Test
  public void shouldProvideStringAsset () throws Exception {
    IStringAsset asset = provider.getStringAsset ( SAMPLE_URL, SAMPLE_AUTH );
    assertNotNull ( asset );
    assertEquals ( SAMPLE_URL, provider.getUrl () );
    assertEquals ( SAMPLE_AUTH, provider.getAuth () );
  }

  @Test(expected=RequestException.class)
  public void shouldRethrowIOExceptions () throws Exception {
    HttpEntity entity = mock ( HttpEntity.class );
    when ( entity.getContent () ).thenThrow ( new IOException ( "fake error" ) );
    when ( expectedResponse.getEntity () ).thenReturn ( entity );

    provider.getStringAsset ( SAMPLE_URL, SAMPLE_AUTH );
  }

  private HttpResponse mockResponse () {
    HttpResponse response = mock ( HttpResponse.class );

    StatusLine statusLine = mock ( StatusLine.class );
    when ( response.getStatusLine () ).thenReturn ( statusLine );
    return response;
  }

  private static class NoHttpAssetProvider extends AssetProvider {
    private Auth auth;
    private String url;
    private HttpResponse response;

    @Override
    protected HttpResponse getResponse ( String url, Auth auth ) throws RequestException {
      this.url = url;
      this.auth = auth;

      return response;
    }

    public Auth getAuth () {
      return auth;
    }

    public String getUrl () {
      return url;
    }

    public void setResponse ( HttpResponse response ) {
      this.response = response;
    }

  }
}
